﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

using IMLibrary.Controls;
using IMLibrary.Security;
using Ourmsg.FileTransmit;
using Ourmsg.Enum;
using Ourmsg.Factory;

using P;
 
using OurMsg.Class;

namespace OurMsg.Controls
{
    public partial class PanelMessage : UserControl
    {
        public PanelMessage()
        {
            InitializeComponent();
            IniControlAndEvents();
        }

        #region 字段
        /// <summary>
        /// 当前用户名
        /// </summary>
        public string UserName = "";
        /// <summary>
        /// 当前用户ID
        /// </summary>
        public UInt32  UserID = 0;

        private Controls.PanelFace panelFace = new Controls.PanelFace();

        /// <summary>
        /// 自定义表情文件发送集合
        /// </summary>
        private Dictionary<string, ImageFile> CustomerImageFiles = new Dictionary<string, ImageFile>();

        #endregion

        #region 事件
        /// <summary>
        /// 发送事件代理
        /// </summary>
        /// <param name="Msg">要发送的消息</param>
        public delegate void CreateMsgEventHandler(object sender, Element Msg);
        /// <summary>
        /// 创建消息事件
        /// </summary>
        public event CreateMsgEventHandler CreateMsgAfter;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void OnCreateMsgAfter(Element msg)
        {
            if (CreateMsgAfter != null)
                CreateMsgAfter(this, msg);
        } 
        #endregion

        #region 设置输入焦点
        /// <summary>
        /// 设置输入焦点
        /// </summary>
        public void SetFocus()
        {
            this.TextSend.Focus();
            this.TextSend.Select();
        }
        #endregion

        #region 添加系统消息
        /// <summary>
        /// 添加系统消息
        /// </summary>
        /// <param name="msg"></param>
        public void AddSystemMessage(string msg)
        {
            if (msg == null || msg == string.Empty)
                return;

            TextRecord.AppendText("【系统消息】" + msg + "\r\n");
        }
        #endregion

        #region 自定义表情或截图操作
        /// <summary>
        /// 获得自定义表情
        /// </summary>
        /// <param name="MD5"></param>
        /// <returns></returns>
        private ImageFile GetCustomerImageFile(string MD5)
        {
            ImageFile f = null;
            CustomerImageFiles.TryGetValue(MD5, out f);
            return f;
        }

        /// <summary>
        /// 上传自定图片文件到服务器
        /// </summary>
        private void UpLoadCustomerImageFile(string MD5)
        {
            var filename = UserID + "\\sendImage\\" + MD5 + ".gif";
            FileInfo file = new FileInfo(filename);
            if (file.Exists)
            {
                var f = GetCustomerImageFile(MD5);
                if (f == null)
                {
                    f = new ImageFile();
                    f.MD5 = MD5;
                    f.State = imageState.uploading;
                    lock (CustomerImageFiles)
                        CustomerImageFiles.Add(MD5, f);

                    TFileInfo tFileInfo = new TFileInfo(MD5, file.Extension);
                    {
                        tFileInfo.fullName = filename;
                        tFileInfo.Length = file.Length;
                        tFileInfo.Name = file.Name;
                    }

                    {
                        f.ImageClient = new Ourmsg.FileTransmit.ImageClientV1(tFileInfo, Global.ServerIP, Global.ImageServerUdpPort, true,true );
                        f.ImageClient.Transmitted += (s, e) =>
                        {
                            f.State = imageState.uploaded;
                            f.ImageClient.Dispose();

                            var msg = new ImageFileMsg(MD5, file.Extension);
                            msg.Length = file.Length;
                            OnCreateMsgAfter(msg);
                            
                        }; 
                    }
                }
            }
        } 
        #endregion

        #region 加载所有表情
        private void PanelMessage_Load(object sender, EventArgs e)
        {
            toolStrip2.FormBackColor = panelTool.BackColor;
            ///初始化表情
            //for (int i = 0; i < Global.ImageFaces.Count; i++)
            //{
            //    panelFace.EcSystemFace.Items.Add(
            //        new IMLibrary.Controls.EmotionPanel.EmotionItem(Global.ImageFaces[i].Tag.ToString(), Global.ImageFaces[i].Tag.ToString(), Global.ImageFaces[i].Clone()));
            //}
            ///初始化表情
            for (int i = 0; i < 99; i++)
            {
                try
                {
                    string fileNamePath =@"face\" + i.ToString() + ".gif";
                    Image image = System.Drawing.Image.FromFile(fileNamePath);
                    image.Tag = i;
                    panelFace.EcSystemFace.Items.Add(new IMLibrary.Controls.EmotionPanel.EmotionItem(i.ToString(), i.ToString(), image));
                }
                catch { }
            } 
        }
        #endregion

        #region 初始化控件及事件
        /// <summary>
        /// 初始化控件及事件
        /// </summary>
        private void IniControlAndEvents()
        {
            TextSend.AllowDrop = true;

            TextSend.KeyDown += (s, e) =>
                {
                    if (e.KeyCode == System.Windows.Forms.Keys.Enter)
                        SendMsg();
                };

            TextSend.KeyUp += (s, e) =>
                {
                    if (e.KeyCode == System.Windows.Forms.Keys.Enter)
                    {
                        TextSend.Clear();
                        TextSend.Focus();
                        TextSend.Select(0, 0);
                    }
                };

            this.tsButFace.Click += (s, e) => panelFace.Show(toolStrip2);

            this.tsButColor.Click += (s, e) =>
            {
                ColorDialog cd = new ColorDialog();
                cd.Color = this.TextSend.ForeColor;
                if (cd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    this.TextSend.ForeColor = cd.Color;
            };

            this.tsButSetFont.Click += (s, e) =>
            {
                FontDialog fd = new FontDialog();
                fd.Font = this.TextSend.Font;
                if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    this.TextSend.Font = fd.Font;
            };

            this.tsButCaptureImageTool.Click += tsButCaptureImageTool_Click;

            panelFace.EcSystemFace.ItemClick += (s, e) =>
                {this. TextSend.AddImage(e.Item.Image.Tag.ToString(), e.Item.Image); };
        }
        #endregion
         
        #region 发送消息
        /// <summary>
        /// Sends currently typed text from active wrie tab.
        /// </summary>
        public void SendMsg()
        {
            try
            {
                string text = "";
                text = TextSend.Text;

                if (text.Length == 0)
                    return;

                P.Message msg = GetSendMsg();
                msg.DateTime = DateTime.Now.ToString();
                msg.From = UserID;
                msg.FromName = UserName;
                if (CreateMsgAfter != null)
                    CreateMsgAfter(this, msg);//触发发送消息事件

                MsgToRichTextBox(msg, true); 
                TextSend.Clear();
            }
            catch (Exception x)
            {
                MessageBox.Show(this, "Error: " + x.ToString(), "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region 获得发送的消息类
        /// <summary>
        /// 获得发送的消息类
        /// </summary>
        /// <returns></returns>
        private  P.Message GetSendMsg()//获得要发送的消息类
        {
            P.Message msg = new  P.Message();
            msg.Content = TextSend.Text.TrimEnd();//获得消息文本内容
            msg.FontBold = TextSend.Font.Bold;
            msg.FontItalic = TextSend.Font.Italic;
            msg.FontName = TextSend.Font.Name;
            msg.FontSize = TextSend.Font.Size;
            msg.FontStrikeout = TextSend.Font.Strikeout;
            msg.FontUnderline = TextSend.Font.Underline;
            msg.FontColor = TextSend.ForeColor.ToArgb();
            msg.ImageInfo = TextSend.GetImageInfo();

            var MD5s = TextSend.GetExistImageMD5s ();
            if (MD5s != null)
                foreach (var md5 in MD5s)
                    if (md5.Length == 32)
                        UpLoadCustomerImageFile(md5);
            return msg;
        }
        #endregion

        #region 将用户对话消息加入 RichTextBox  
        /// <summary>
        /// 将用户对话消息加入 RichTextBox  
        /// </summary>
        /// <param name="msg">消息类</param>
        /// <param name="IsSend">标记是发送消息还是收到消息</param>
        /// <param name="title">标题（用户名+用户ID）</param>
        public void MsgToRichTextBox(P.Message msg, bool IsSend = false)//将发送的消息加入历史rich
        {
            int iniPos = this.TextRecord.TextLength;//获得当前记录richBox中最后的位置 
            Color titleColor = Color.Red;
            var title = string.Format("{0}({1}){2}", msg.FromName, msg.From, msg.DateTime);
            if (!IsSend)//如果是收到消息
                titleColor = Color.Blue;

            if (msg.Content == null) msg.Content = "";

            TextRecord.AppendText(title);
            TextRecord.Select(iniPos, TextRecord.TextLength - iniPos);
            TextRecord.SelectionFont = new Font("宋体", 10);
            TextRecord.SelectionColor = titleColor;

            TextRecord.AppendText("\n ");

            iniPos = TextRecord.TextLength;//获得当前记录richBox中最后的位置

            #region 如果消息中有图片，则添加图片
            if (msg.ImageInfo != null && msg.ImageInfo != "")//如果消息中有图片，则添加图片
            {
                string[] imagePos = msg.ImageInfo.Split(';');
                int addPos = 0;//
                int currPos = 0;//当前正要添加的文本位置
                int textPos = 0;
                for (int i = 0; i < imagePos.Length - 1; i++)
                {
                    string[] imageContent = imagePos[i].Split(',');//获得图片所在的位置、图片名称 
                    currPos = Convert.ToInt32(imageContent[0]);//获得图片所在的位置

                    TextRecord.AppendText(msg.Content.Substring(textPos, currPos - addPos));
                    TextRecord.SelectionStart = TextRecord.TextLength;

                    textPos += currPos - addPos;
                    addPos += currPos - addPos;

                    Image image = null;

                    if (IsSend)//如果图片是自己发送给自己的
                        image = this.TextSend.GetImage(imageContent[1]);
                    else//如果图片是对方发送过来的
                    {
                        image = TextRecord.GetImage(imageContent[1]);
                        if (image == null)
                            if (imageContent[1].Length < 32)
                                image = System.Drawing.Image.FromFile(Application.StartupPath + @"\face\" + imageContent[1] + ".gif");
                            else
                            {
                                string fileName = UserID + @"\ArrivalImage\" + imageContent[1] + ".gif";
                                if (System.IO.File.Exists(fileName)) //如果本地已经有此文件已经存在 
                                    image = System.Drawing.Image.FromFile(fileName);
                            }
                    }

                    if (image == null)
                    {
                        image = Properties.Resources.Wait;
                        TextRecord.AddImage(imageContent[1], image);
                    }
                    else
                        TextRecord.AddImage(imageContent[1], image);

                    addPos++;
                }
                TextRecord.AppendText(msg.Content.Substring(textPos, msg.Content.Length - textPos) + "  \n");
            }
            #endregion

            #region 如果消息中没有图片，则直接添加消息文本
            else//如果消息中没有图片，则直接添加消息文本
            {
                TextRecord.AppendText(msg.Content + "\n");
            }
            #endregion

            TextRecord.Select(iniPos, TextRecord.TextLength - iniPos);
            TextRecord.SelectionFont = CreateFont.GetFont(msg);
            TextRecord.SelectionColor = CreateFont.GetColor(msg);

            TextRecord.Select(TextRecord.TextLength, 0);
            TextRecord.ScrollToCaret();
        }
        #endregion

        #region 更新自定义图片
        /// <summary>
        /// 更新自定义图片
        /// </summary>
        /// <param name="MD5"></param>
        /// <param name="image"></param>
        public void UpdateImage(string MD5, Image image)
        {
            this.TextRecord.UpdateImage(MD5, image);
        }
        #endregion

        #region 截图
        void tsButCaptureImageTool_Click(object sender, EventArgs e)
        {
            var ct = new IMLibrary.Controls.CaptureImage.CaptureImageTool();
            if (ct.ShowDialog() == DialogResult.OK)
            {
                Image image = ct.Image;
                if (image != null)
                {
                    System.IO.DirectoryInfo dInfo = new System.IO.DirectoryInfo(UserID  + "\\sendImage");
                    if (!dInfo.Exists)
                        dInfo.Create();

                    string fileName = UserID  + "\\sendImage\\temp.gif";
                    image.Save(fileName);
                    string md5 = Hasher.GetMD5Hash(fileName);
                    string Md5fileName = UserID + "\\sendImage\\" + md5 + ".gif";

                    if (!System.IO.File.Exists(Md5fileName))
                    {
                        System.IO.File.Delete(fileName);
                        image.Save(Md5fileName);
                    }
                    this.TextSend.AddImage(md5,image);
                    this.TextSend.Focus();
                }
            }
        }
        #endregion
    }
}
